<!DOCTYPE html>
<html>
<head>
    <!-- hexo-inject:begin --><!-- hexo-inject:end --><title>博望</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css">
    <link href="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css">
    <script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    
<link rel="stylesheet" href="/css/prism.css">
 
    
<script src="/js/prism.js"></script>

    
    
<link rel="stylesheet" href="/css/index.css">
 
    
<script src="/js/search.js"></script>



     
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML" async></script>
        <script type="text/x-mathjax-config">
            MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
        </script>
     

     
        <script src="//lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js"> </script>
        
<script src="/js/fancybox.js"></script>

    

    <script type="text/javascript">
        var search_path = "search.xml";
        if (search_path.length == 0) {
            search_path = "search.xml";
        }
        var path = "/" + search_path;
        searchFunc(path, 'local-search-input', 'local-search-result');
    </script>
<!-- hexo injector head_end start -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/themes/prism.css">
<!-- hexo injector head_end end --><meta name="generator" content="Hexo 6.1.0"><!-- hexo-inject:begin --><!-- hexo-inject:end --></head>

    <style>
        .row2 {
            /* --bs-gutter-x: 2.5rem;
            --bs-gutter-y: 0;
            display: flex;
            flex-wrap: wrap;
            margin-top: calc(var(--bs-gutter-y) * -20);
            margin-right: calc(var(--bs-gutter-x) * -2);
            margin-left: calc(var(--bs-gutter-x) * -2); */
        }

        .row-0 {
            width: 0;
        }
    </style>

    <body id="body">
        <!-- hexo-inject:begin --><!-- hexo-inject:end --><!-- 导航栏 -->
        <nav class="navbar navbar-expand-md navbar-dark mb-4 pt-3 pb-3">
    <div class="container" style="display: flex;flex-direction: row;align-items: flex-end;">
        <div style="display: flex;flex-direction: column;">
            <a class="navbar-brand" style='font: bold 29px "Times New Roman", Georgia, Times, sans-serif;
        color: #555;' href="/ ">
                博望
            </a>
            <span style="padding-bottom:7px;padding-right:20px">
                博望不熄
            </span>
        </div>

        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse"
            aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="navbarCollapse">
            <ul class="navbar-nav me-auto mb-2 mb-md-0" style="color: #555;">
                
 
 

    <li class="nav-item">
        <a class="nav-link" style="color: #555;" href="/">
            <i class="fa fa-home "> </i> 主页
        </a>
    </li>

    <li class="nav-item">
        <a class="nav-link" style="color: #555;" href="/archives">
            <i class="fa fa-archive" "> </i> 归档
        </a>
    </li>
 

            </ul>

            
                <form class="d-flex">
                    <button class="btn text-muted fa fa-search d-none d-md-block d-lg-block" disabled></button>
                    <input id="local-search-input" class="form-control me-2 pe-4" type="search"
                        placeholder="搜索 " aria-label="Search">
                </form>
                

                    <ul class="navbar-nav">
                        
 

                    </ul>
        </div>
    </div>
</nav>

            <main class="container">
                <div class="row row2 pt-3">
                    <!-- 文章 -->
                    <div id="content" class="col-md-12">
                        <div class="markdown-section">
                            <!-- 搜索结果 -->
                            <div id="local-search-result"></div>
                            <!-- 博客详情 -->
<p class="h1">QuickJS数字字面量</p>

<div class="pb-3">
    <i class="fa fa-calendar p-1"></i>
    2022/05/12 22:20:32 

    <i class="fa fa-folder-open p-1"> </i> 
    <span class="tag-hover">
         
    </span>

    <i class="fa fa-tag p-1"> </i>
    <span class="tag-hover">
        
            <a href="/tags/QuickJS/" class="link-dark text-decoration-none"> 
                QuickJS 
            </a>
        
    </span>
</div>

<h2 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h2><p>QuickJS是Fabrice Bellard在2019年发布的一款支持ES6的JavaScript引擎。Fabrice Bellard是一位富有传奇经历的大佬。自己独立开发、发起和维护的耀眼明星项目有：FFmpeg、TCC、QEMU、JSLinux和LTEENB等等。FFmpeg是一个开源音视频处理库，提供了简单便捷统一的音视频处理接口，将广大的音视频开发程序员从音视频开发苦海中解放出来。QEMU是一个模拟器框架，绝大多数PC上的安卓模拟器都是基于它开发出来的。TCC是x86架构下，世界上最快的C语言编译器。JSLinux更是神，直接将linux系统运行到浏览器中。你以为这就完了？他一个人用10个月的时间，开发了一个可以在PC机上运行的4G LTE&#x2F;5G NR基站程序。仅仅10个月啊，我连协议都看不完😓。毫不夸张的说，可能他一个人至少养活了全球上万个程序员。</p>
<h2 id="QuickJS运行JavaScript原理"><a href="#QuickJS运行JavaScript原理" class="headerlink" title="QuickJS运行JavaScript原理"></a>QuickJS运行JavaScript原理</h2><p>QuickJS在运行JavaScript源码时，先解析源码，源码解析成token，再根据生成字节码。字节码由操作码、操作数和标签组成。然后再对字节码进行优化。最后，再遍历字节码，根据操作码和操作数，执行操作和计算。<br>解析源码依赖的是Token。根据TC39制定的ECMAScript词法定义，将ECMAScript通用Token分成了以下几种</p>
<ul>
<li>IndentifierName</li>
<li>PraviteIndentifier</li>
<li>Punctuator</li>
<li>NumbericLiteral</li>
<li>StringLiteral</li>
<li>Template</li>
</ul>
<h2 id="数字字面量"><a href="#数字字面量" class="headerlink" title="数字字面量"></a>数字字面量</h2><p>我们这篇文章的目的介绍大佬如何解析NumbericLiteral的。NumbericLiteral的意思是数字字面量。可能有同学学编程时，没有注意到字面量的定义，有点不太理解含义。字面量(literal)是用于表达一个固定值的表示法，又叫常量。举个例子：</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">10</span>
<span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token string">"hello,world"</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"nice~~~"</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>这个例子中，有两个变量分别是x和y。例子中还有三个字面量，其中有一个数字字面量、两个字符串字面量，分别是：10，”hello,world”， “nice~~~”。</p>
<ul>
<li>这里的数字就是数学意义上的数字。</li>
<li>数字字面量区分:整数字面量、浮点数字面量(小数)、特殊值。</li>
<li>书写时直接书写字面量，不需要添加任何辅助符号。<br>科学计数法<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token number">123e5</span><span class="token punctuation">;</span>    <span class="token comment">// 12300000</span>
<span class="token keyword">var</span> z <span class="token operator">=</span> <span class="token number">123e-5</span><span class="token punctuation">;</span>   <span class="token comment">// 0.00123</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li>
</ul>
<p>JavaScript 数值始终是 64 位的浮点数,JavaScript 数值始终以双精度浮点数来存储，根据国际 IEEE 754 标准。</p>
<h3 id="整数"><a href="#整数" class="headerlink" title="整数"></a>整数</h3><p>整数字面量写法区分进制。可以被表示成十进制、八进制以及十六进制。在进行算术计算时或者参与程序，所有八进制和十六进制的数字都会被转换成十进制。</p>
<h4 id="十进制"><a href="#十进制" class="headerlink" title="十进制"></a>十进制</h4><p>十进制最基本的数值字面量格式，基数为10。逢十进一，每个位数只能是0-9之间的数字。</p>
<h4 id="八进制"><a href="#八进制" class="headerlink" title="八进制"></a>八进制</h4><p>八进制字面量必须带前导0、0O、0o。基数为8。逢八进一，每个位数只能是0-7之间的数字。（如果以0开头，每个位数上有超过0-7之间的数字出现，也就是8&#x2F;9，强制忽视前面的0，直接将后面数字当做十进制）<br>下面是八进制转十进制的方法:</p>
<blockquote>
<p>0O011 &#x3D; 0 * 8^2 + 1 * 8^1 + 1 * 8^0 &#x3D; 9</p>
</blockquote>
<h4 id="十六进制"><a href="#十六进制" class="headerlink" title="十六进制"></a>十六进制</h4><p>十六进制字面量必须带前缀0x和0X。基数为16。逢十六进一，每个位数只能是数字0-9、字母a-f或A~F。<br>下面是十六进制转十进制的方法:</p>
<blockquote>
<p>0x01000 &#x3D; 0 * 16^0 + 0 * 16^1 + 0 * 16^2 +1 * 16^3 + 0 * 16^4 &#x3D; 4096</p>
</blockquote>
<h4 id="浮点数"><a href="#浮点数" class="headerlink" title="浮点数"></a>浮点数</h4><p>数学概念中的小数，浮点数不区分进制，所有的浮点数都是十进制下的数字。<br>注意：如果浮点数是大于0小于1的，可以省略小数点前面的0不写。<br>浮点数值的最高精度是17位小数，但在进行算术计算时其精确度远远不如整数。<br>例如：0.1+0.2；结果不是0.3，而是:0.30000000000000004</p>
<h4 id="Infinity-无穷"><a href="#Infinity-无穷" class="headerlink" title="Infinity 无穷"></a>Infinity 无穷</h4><p>Infinity （或 -Infinity）是 JavaScript 在计算数时超出最大可能数范围时返回的值。<br>Infinity本身就是一个数字。</p>
<ul>
<li>最小值:Number.MIN_VALUE，这个值为: 5e-324</li>
<li>最大值:Number.MAX_VALUE，这个值为: 1.7976931348623157e+308</li>
<li>无穷大:Infinity</li>
<li>无穷小:-Infinity</li>
</ul>
<h4 id="NaN-非数值"><a href="#NaN-非数值" class="headerlink" title="NaN 非数值"></a>NaN 非数值</h4><ul>
<li>NaN:not a number表示不是一个正常的数，但是还是一个 Number 类型的数字。这个数字 没办法用前面的表示方法表示。</li>
<li>NaN与任何值都不相等，包括他本身。</li>
<li>isNaN():判断一个数据是不是一个NaN。</li>
</ul>
<h2 id="补课"><a href="#补课" class="headerlink" title="补课"></a>补课</h2><h3 id="ASCII"><a href="#ASCII" class="headerlink" title="ASCII"></a>ASCII</h3><p>为了让更多基础不强的同学能看懂，在此补下课。关于ASCII，引用下面的百度定义。我们存储类似英文字母、阿拉伯数字、英文标点符号等字符串到文本中，一般都遵循ASCII标准。比如，我们存储字符’A’到文本中，存储的不是字符‘A’，而是一个数字，这个数字就是ASCII表中，字符’A’对应的数字– 65。<br>ASCII ((American Standard Code for Information Interchange): 美国信息交换标准代码）是基于拉丁字母的一套电脑编码系统，主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准，并等同于国际标准ISO&#x2F;IEC 646。ASCII第一次以规范标准的类型发表是在1967年，最后一次更新则是在1986年，到目前为止共定义了128个字符<br><img src="https://img-blog.csdnimg.cn/7552a9ddb00c4a948e7303c1ef5e0c52.png" alt="ASCII表"></p>
<h2 id="将数字字面量转化成数字"><a href="#将数字字面量转化成数字" class="headerlink" title="将数字字面量转化成数字"></a>将数字字面量转化成数字</h2><p> QuickJS将JavaScript代码先当作字符串读入内存。然后逐字节遍历这个字符串，当判断某一个字节的在字符 ‘0’ 和字符 ‘9’ 之间时，认为识别到了数字字面量的起始位置。然后该字符串，转化成数字。<br>比如上面的例子中的第一行，程序从第一个字符 ‘l’ （’let’的第一个字符l）开始遍历，直到第9个字符，发现是字符 ‘1’ ,  正好处于字符 ‘0’ 和字符 ‘9’ 之间。这时，程序认为这可能是一个数字字面量的开始。需要注意的是  ‘ ‘ – 空白也是一个字符，占用一个字节长度。然后继续遍历，直到下一个空字符。这很好理解，因为数字字面量是连续的，中间不能包含有空字符。<br>如此，我们便得到了一个完整的数字字面量 – 10。此时，它还是个字符串。如何将它解析成数字呢？看看大佬是如何做的。js_atof是将字符串转化成数字的函数，我们先放出来它的源码。</p>
<pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">ATOD_INT_ONLY</span>        <span class="token expression"><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span></span></span>
<span class="token comment">/* accept Oo and Ob prefixes in addition to 0x prefix if radix = 0 */</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">ATOD_ACCEPT_BIN_OCT</span>  <span class="token expression"><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">2</span><span class="token punctuation">)</span></span></span>
<span class="token comment">/* accept O prefix as octal if radix == 0 and properly formed (Annex B) */</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">ATOD_ACCEPT_LEGACY_OCTAL</span>  <span class="token expression"><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">4</span><span class="token punctuation">)</span></span></span>
<span class="token comment">/* accept _ between digits as a digit separator */</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">ATOD_ACCEPT_UNDERSCORES</span>  <span class="token expression"><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">5</span><span class="token punctuation">)</span></span></span>
<span class="token comment">/* allow a suffix to override the type */</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">ATOD_ACCEPT_SUFFIX</span>    <span class="token expression"><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">6</span><span class="token punctuation">)</span> </span></span>
<span class="token comment">/* accept -0x1 */</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">ATOD_ACCEPT_PREFIX_AFTER_SIGN</span> <span class="token expression"><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">10</span><span class="token punctuation">)</span></span></span>

<span class="token keyword">static</span> JSValue <span class="token function">js_atof</span><span class="token punctuation">(</span>JSContext <span class="token operator">*</span>ctx<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>str<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span><span class="token operator">*</span>pp<span class="token punctuation">,</span>
                       <span class="token keyword">int</span> radix<span class="token punctuation">,</span> <span class="token keyword">int</span> flags<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>p<span class="token punctuation">,</span> <span class="token operator">*</span>p_start<span class="token punctuation">;</span>
    <span class="token keyword">int</span> sep<span class="token punctuation">,</span> is_neg<span class="token punctuation">;</span>
    BOOL is_float<span class="token punctuation">,</span> has_legacy_octal<span class="token punctuation">;</span>
    <span class="token keyword">int</span> atod_type <span class="token operator">=</span> flags <span class="token operator">&amp;</span> ATOD_TYPE_MASK<span class="token punctuation">;</span>
    <span class="token keyword">char</span> buf1<span class="token punctuation">[</span><span class="token number">64</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">*</span>buf<span class="token punctuation">;</span>
    <span class="token keyword">int</span> i<span class="token punctuation">,</span> j<span class="token punctuation">,</span> len<span class="token punctuation">;</span>
    BOOL buf_allocated <span class="token operator">=</span> FALSE<span class="token punctuation">;</span>
    JSValue val<span class="token punctuation">;</span>
    
    <span class="token comment">/* optional separator between digits */</span>
    sep <span class="token operator">=</span> <span class="token punctuation">(</span>flags <span class="token operator">&amp;</span> ATOD_ACCEPT_UNDERSCORES<span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token char">'_'</span> <span class="token operator">:</span> <span class="token number">256</span><span class="token punctuation">;</span>
    has_legacy_octal <span class="token operator">=</span> FALSE<span class="token punctuation">;</span>
    
    p <span class="token operator">=</span> str<span class="token punctuation">;</span>
    p_start <span class="token operator">=</span> p<span class="token punctuation">;</span>
    is_neg <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>p<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'+'</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        p<span class="token operator">++</span><span class="token punctuation">;</span>
        p_start<span class="token operator">++</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>flags <span class="token operator">&amp;</span> ATOD_ACCEPT_PREFIX_AFTER_SIGN<span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token keyword">goto</span> no_radix_prefix<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>p<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'-'</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        p<span class="token operator">++</span><span class="token punctuation">;</span>
        p_start<span class="token operator">++</span><span class="token punctuation">;</span>
        is_neg <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>flags <span class="token operator">&amp;</span> ATOD_ACCEPT_PREFIX_AFTER_SIGN<span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token keyword">goto</span> no_radix_prefix<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>p<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'0'</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'x'</span> <span class="token operator">||</span> p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'X'</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>
            <span class="token punctuation">(</span>radix <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">||</span> radix <span class="token operator">==</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            p <span class="token operator">+=</span> <span class="token number">2</span><span class="token punctuation">;</span>
            radix <span class="token operator">=</span> <span class="token number">16</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'o'</span> <span class="token operator">||</span> p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'O'</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>
                   radix <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>flags <span class="token operator">&amp;</span> ATOD_ACCEPT_BIN_OCT<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            p <span class="token operator">+=</span> <span class="token number">2</span><span class="token punctuation">;</span>
            radix <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'b'</span> <span class="token operator">||</span> p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'B'</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>
                   radix <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>flags <span class="token operator">&amp;</span> ATOD_ACCEPT_BIN_OCT<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            p <span class="token operator">+=</span> <span class="token number">2</span><span class="token punctuation">;</span>
            radix <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">>=</span> <span class="token char">'0'</span> <span class="token operator">&amp;&amp;</span> p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">&lt;=</span> <span class="token char">'9'</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>
                   radix <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>flags <span class="token operator">&amp;</span> ATOD_ACCEPT_LEGACY_OCTAL<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token keyword">int</span> i<span class="token punctuation">;</span>
            has_legacy_octal <span class="token operator">=</span> TRUE<span class="token punctuation">;</span>
            sep <span class="token operator">=</span> <span class="token number">256</span><span class="token punctuation">;</span>
            <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">(</span>p<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">>=</span> <span class="token char">'0'</span> <span class="token operator">&amp;&amp;</span> p<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">&lt;=</span> <span class="token char">'7'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
                <span class="token keyword">continue</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>p<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'8'</span> <span class="token operator">||</span> p<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'9'</span><span class="token punctuation">)</span>
                <span class="token keyword">goto</span> no_prefix<span class="token punctuation">;</span>
            p <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">;</span>
            radix <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
            <span class="token keyword">goto</span> no_prefix<span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token comment">/* there must be a digit after the prefix */</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">to_digit</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint8_t</span><span class="token punctuation">)</span><span class="token operator">*</span>p<span class="token punctuation">)</span> <span class="token operator">>=</span> radix<span class="token punctuation">)</span>
            <span class="token keyword">goto</span> fail<span class="token punctuation">;</span>
    no_prefix<span class="token operator">:</span> <span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
 no_radix_prefix<span class="token operator">:</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>flags <span class="token operator">&amp;</span> ATOD_INT_ONLY<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>
            <span class="token punctuation">(</span>atod_type <span class="token operator">==</span> ATOD_TYPE_FLOAT64 <span class="token operator">||</span>
             atod_type <span class="token operator">==</span> ATOD_TYPE_BIG_FLOAT<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>
            <span class="token function">strstart</span><span class="token punctuation">(</span>p<span class="token punctuation">,</span> <span class="token string">"Infinity"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>p<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token punctuation">&#123;</span>
                <span class="token keyword">double</span> d <span class="token operator">=</span> <span class="token number">1.0</span> <span class="token operator">/</span> <span class="token number">0.0</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>is_neg<span class="token punctuation">)</span>
                    d <span class="token operator">=</span> <span class="token operator">-</span>d<span class="token punctuation">;</span>
                val <span class="token operator">=</span> <span class="token function">JS_NewFloat64</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> d<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
            <span class="token keyword">goto</span> done<span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>radix <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span>
        radix <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
    is_float <span class="token operator">=</span> FALSE<span class="token punctuation">;</span>
    p_start <span class="token operator">=</span> p<span class="token punctuation">;</span><span class="token comment">//计算有效数字开始的地方，有效数字指的是出去进制符号信息的数字，如：+0x988 中 988 就是有效数字</span>
    
    <span class="token comment">//跳过满足进制要求的字符</span>
    <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token function">to_digit</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint8_t</span><span class="token punctuation">)</span><span class="token operator">*</span>p<span class="token punctuation">)</span> <span class="token operator">&lt;</span> radix
           <span class="token operator">||</span>  <span class="token punctuation">(</span><span class="token operator">*</span>p <span class="token operator">==</span> sep <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>radix <span class="token operator">!=</span> <span class="token number">10</span> <span class="token operator">||</span>
                              p <span class="token operator">!=</span> p_start <span class="token operator">+</span> <span class="token number">1</span> <span class="token operator">||</span> p<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token char">'0'</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>
                <span class="token function">to_digit</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint8_t</span><span class="token punctuation">)</span>p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> radix<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        p<span class="token operator">++</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>flags <span class="token operator">&amp;</span> ATOD_INT_ONLY<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token comment">// 判断是否是浮点数字中出现的小数点</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span>p <span class="token operator">==</span> <span class="token char">'.'</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>p <span class="token operator">></span> p_start <span class="token operator">||</span> <span class="token function">to_digit</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint8_t</span><span class="token punctuation">)</span>p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> radix<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            is_float <span class="token operator">=</span> TRUE<span class="token punctuation">;</span>
            p<span class="token operator">++</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span>p <span class="token operator">==</span> sep<span class="token punctuation">)</span>
                <span class="token keyword">goto</span> fail<span class="token punctuation">;</span>
            <span class="token comment">//跳过满足进制要求的字符</span>
            <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token function">to_digit</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint8_t</span><span class="token punctuation">)</span><span class="token operator">*</span>p<span class="token punctuation">)</span> <span class="token operator">&lt;</span> radix <span class="token operator">||</span>
                   <span class="token punctuation">(</span><span class="token operator">*</span>p <span class="token operator">==</span> sep <span class="token operator">&amp;&amp;</span> <span class="token function">to_digit</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint8_t</span><span class="token punctuation">)</span>p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> radix<span class="token punctuation">)</span><span class="token punctuation">)</span>
                p<span class="token operator">++</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token comment">//科学计数法</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>p <span class="token operator">></span> p_start <span class="token operator">&amp;&amp;</span>
            <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>p <span class="token operator">==</span> <span class="token char">'e'</span> <span class="token operator">||</span> <span class="token operator">*</span>p <span class="token operator">==</span> <span class="token char">'E'</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> radix <span class="token operator">==</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token operator">||</span>
             <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token operator">*</span>p <span class="token operator">==</span> <span class="token char">'p'</span> <span class="token operator">||</span> <span class="token operator">*</span>p <span class="token operator">==</span> <span class="token char">'P'</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>radix <span class="token operator">==</span> <span class="token number">2</span> <span class="token operator">||</span> radix <span class="token operator">==</span> <span class="token number">8</span> <span class="token operator">||</span> radix <span class="token operator">==</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>p1 <span class="token operator">=</span> p <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
            is_float <span class="token operator">=</span> TRUE<span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span>p1 <span class="token operator">==</span> <span class="token char">'+'</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                p1<span class="token operator">++</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span>p1 <span class="token operator">==</span> <span class="token char">'-'</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                p1<span class="token operator">++</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">is_digit</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint8_t</span><span class="token punctuation">)</span><span class="token operator">*</span>p1<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                p <span class="token operator">=</span> p1 <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
                <span class="token comment">//遍历跳过所有数字</span>
                <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token function">is_digit</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint8_t</span><span class="token punctuation">)</span><span class="token operator">*</span>p<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">(</span><span class="token operator">*</span>p <span class="token operator">==</span> sep <span class="token operator">&amp;&amp;</span> <span class="token function">is_digit</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint8_t</span><span class="token punctuation">)</span>p<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                    p<span class="token operator">++</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>p <span class="token operator">==</span> p_start<span class="token punctuation">)</span>
        <span class="token keyword">goto</span> fail<span class="token punctuation">;</span>

    buf <span class="token operator">=</span> buf1<span class="token punctuation">;</span>
    buf_allocated <span class="token operator">=</span> FALSE<span class="token punctuation">;</span>
    len <span class="token operator">=</span> p <span class="token operator">-</span> p_start<span class="token punctuation">;</span><span class="token comment">//得到有效数字部分字符串长度</span>
    <span class="token comment">//看看buf够不够用，不够就重新申请</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span><span class="token punctuation">(</span>len <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>buf1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        buf <span class="token operator">=</span> <span class="token function">js_malloc_rt</span><span class="token punctuation">(</span>ctx<span class="token operator">-></span>rt<span class="token punctuation">,</span> len <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* no exception raised */</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>buf<span class="token punctuation">)</span>
            <span class="token keyword">goto</span> mem_error<span class="token punctuation">;</span>
        buf_allocated <span class="token operator">=</span> TRUE<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token comment">// 移除分隔符和进制前缀</span>
    <span class="token comment">/* remove the separators and the radix prefixes */</span>
    j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token comment">//加上负号</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>is_neg<span class="token punctuation">)</span>
        buf<span class="token punctuation">[</span>j<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token char">'-'</span><span class="token punctuation">;</span>
    <span class="token comment">//移除分隔符</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> len<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>p_start<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token char">'_'</span><span class="token punctuation">)</span>
            buf<span class="token punctuation">[</span>j<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> p_start<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token comment">//截断字符串</span>
    buf<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token char">'\0'</span><span class="token punctuation">;</span>
    
    <span class="token punctuation">&#123;</span>
        <span class="token keyword">double</span> d<span class="token punctuation">;</span>
        <span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span>has_legacy_octal<span class="token punctuation">;</span>
        <span class="token comment">//非十进制小数不符合规则</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>is_float <span class="token operator">&amp;&amp;</span> radix <span class="token operator">!=</span> <span class="token number">10</span><span class="token punctuation">)</span>
            <span class="token keyword">goto</span> fail<span class="token punctuation">;</span>
        <span class="token comment">//将字符串转化成double</span>
        d <span class="token operator">=</span> <span class="token function">js_strtod</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> radix<span class="token punctuation">,</span> is_float<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">//封装成JSValue</span>
        val <span class="token operator">=</span> <span class="token function">JS_NewFloat64</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> d<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

done<span class="token operator">:</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>buf_allocated<span class="token punctuation">)</span>
        <span class="token function">js_free_rt</span><span class="token punctuation">(</span>ctx<span class="token operator">-></span>rt<span class="token punctuation">,</span> buf<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>pp<span class="token punctuation">)</span>
        <span class="token operator">*</span>pp <span class="token operator">=</span> p<span class="token punctuation">;</span>
    <span class="token keyword">return</span> val<span class="token punctuation">;</span>
 fail<span class="token operator">:</span>
    val <span class="token operator">=</span> JS_NAN<span class="token punctuation">;</span>
    <span class="token keyword">goto</span> done<span class="token punctuation">;</span>
 mem_error<span class="token operator">:</span>
    val <span class="token operator">=</span> <span class="token function">JS_ThrowOutOfMemory</span><span class="token punctuation">(</span>ctx<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">goto</span> done<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>代码很简洁。这个函数的参数有五个，为了简化难度，我们只关注其中的两个即可，他们是：const char *str, int radix。第一个参数是字符串，第二个参数是数字的进制。<br>进入程序之后，首先判断是否支持数字表达式中的下划线分割符，比如“9_9_9”。<br>接着判断字面量中是否存在符号。如果存在 ‘-’ ，则表明这个数字是负数。其中，如果设置了允许在符号之后接受前缀，就判断进制。如果不允许在符号之后接受进制标签，就跳过进制判断。<br>然后，判断数字的进制：二进制、八进制、十六进制或十进制（默认）。判断的方式是：先看看符号后一位（如果有）是不是 ‘0’ ，如果是0，就判断第二位。如果第二位是 ‘x’ 或 ‘X’，则表明是十六进制。如果第二位是 ‘b’ 或 ‘B’ ，则表明是二进制。八进制的判断稍微复杂一些，首先要区分是否是js是否运行在严苛模式，如果是，不允许以八进制表示字面量。如果不是，判断第二位是否为 ‘o’ 或 ‘O’，如果是，就说明是八进制。如果不是，再判断是否支持老式八进制表达式。先前版本的八进制表达时是以 ‘0’ 开头，后面是其它数字，没有进制符号。当然，十进制表示时，也有可能是以0开始的。那么如何区分两种进制呢？遍历这个数字字面量，判断这个字符串中是否包含字符 ‘8’ 和 ‘9’，如果是，那么这个数就是十进制，否则是八进制。因为八进制字面量中不可能存在 ‘8’ 和 ‘9’，两个字符。最后，需要再确认下hex进制标识符后面一个字符是否是符合进制的数字。比如：如果是十进制，只能在 ‘0’ 到 ‘9’ 中间；如果是十六进制，只能在 ‘0’ 到 ‘F’ 之间。<br>如果数字不是以 ‘0’ 开头，或者有符号标签同时不支持进制标签，就会判断数字是否是Infinity。如果是就，直接将 1除以0 得到正无穷大，如果前面判断是负的，就直接加上负号得到无穷小。最后，封装成JSValue，返回。如果不是Infinity，则继续下面的处理。<br>在进入转换数字之前，需要再次确认下字面量中，是否所有的数字都满足对应进制的要求。再移除掉字符串中的分隔符和进制标识符。<br>然后继续遍历字符串，直到字符不是数字为止。考虑到数字字面了可能存在小数点和科学计数法表达式。如果发现存在小数点，说明这个数字是个浮点型数字。之后，发现需要分别判断并继续遍历小数点或科学计数法后面的数字。<br>得到完整有效字面量字符串之后，调用 js_strtod() 函数来将字面量转换成double数字。这个函数的代码如下：</p>
<pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">/* XXX: remove */</span>
<span class="token keyword">static</span> <span class="token keyword">double</span> <span class="token function">js_strtod</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>p<span class="token punctuation">,</span> <span class="token keyword">int</span> radix<span class="token punctuation">,</span> BOOL is_float<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    <span class="token keyword">double</span> d<span class="token punctuation">;</span>
    <span class="token keyword">int</span> c<span class="token punctuation">;</span>
    
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>is_float <span class="token operator">||</span> radix <span class="token operator">!=</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token class-name">uint64_t</span> n_max<span class="token punctuation">,</span> n<span class="token punctuation">;</span>
        <span class="token keyword">int</span> int_exp<span class="token punctuation">,</span> is_neg<span class="token punctuation">;</span>
        
        is_neg <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span>p <span class="token operator">==</span> <span class="token char">'-'</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            is_neg <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
            p<span class="token operator">++</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>

        <span class="token comment">/* skip leading zeros */</span>
        <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">*</span>p <span class="token operator">==</span> <span class="token char">'0'</span><span class="token punctuation">)</span>
            p<span class="token operator">++</span><span class="token punctuation">;</span>
        n <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>radix <span class="token operator">==</span> <span class="token number">10</span><span class="token punctuation">)</span>
            n_max <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token number">1</span> <span class="token operator">-</span> <span class="token number">9</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment">/* most common case */</span>
        <span class="token keyword">else</span>
            n_max <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token number">1</span> <span class="token operator">-</span> <span class="token punctuation">(</span>radix <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">/</span> radix<span class="token punctuation">;</span>
        <span class="token comment">/* XXX: could be more precise */</span>
        int_exp <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">*</span>p <span class="token operator">!=</span> <span class="token char">'\0'</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            c <span class="token operator">=</span> <span class="token function">to_digit</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint8_t</span><span class="token punctuation">)</span><span class="token operator">*</span>p<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">>=</span> radix<span class="token punctuation">)</span>
                <span class="token keyword">break</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">&lt;=</span> n_max<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                n <span class="token operator">=</span> n <span class="token operator">*</span> radix <span class="token operator">+</span> c<span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
                int_exp<span class="token operator">++</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
            p<span class="token operator">++</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        d <span class="token operator">=</span> n<span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>int_exp <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            d <span class="token operator">*=</span> <span class="token function">pow</span><span class="token punctuation">(</span>radix<span class="token punctuation">,</span> int_exp<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>is_neg<span class="token punctuation">)</span>
            d <span class="token operator">=</span> <span class="token operator">-</span>d<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
        d <span class="token operator">=</span> <span class="token function">strtod</span><span class="token punctuation">(</span>p<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token keyword">return</span> d<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>如果是十进制数整数，直接调用c标准库中的strtod直接将字符串转换成double类型数字。如果不是十进制数字整数或者是其它进制数字，会将其转换成十进制数字。</p>
<h3 id="to-digit"><a href="#to-digit" class="headerlink" title="to_digit"></a>to_digit</h3><p>将字符串转成数字（按照ASCII表看就会明白）</p>
<pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> <span class="token keyword">inline</span> <span class="token keyword">int</span> <span class="token function">to_digit</span><span class="token punctuation">(</span><span class="token keyword">int</span> c<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">>=</span> <span class="token char">'0'</span> <span class="token operator">&amp;&amp;</span> c <span class="token operator">&lt;=</span> <span class="token char">'9'</span><span class="token punctuation">)</span>
        <span class="token keyword">return</span> c <span class="token operator">-</span> <span class="token char">'0'</span><span class="token punctuation">;</span>
    <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">>=</span> <span class="token char">'A'</span> <span class="token operator">&amp;&amp;</span> c <span class="token operator">&lt;=</span> <span class="token char">'Z'</span><span class="token punctuation">)</span>
        <span class="token keyword">return</span> c <span class="token operator">-</span> <span class="token char">'A'</span> <span class="token operator">+</span> <span class="token number">10</span><span class="token punctuation">;</span>
    <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">>=</span> <span class="token char">'a'</span> <span class="token operator">&amp;&amp;</span> c <span class="token operator">&lt;=</span> <span class="token char">'z'</span><span class="token punctuation">)</span>
        <span class="token keyword">return</span> c <span class="token operator">-</span> <span class="token char">'a'</span> <span class="token operator">+</span> <span class="token number">10</span><span class="token punctuation">;</span>
    <span class="token keyword">else</span>
        <span class="token keyword">return</span> <span class="token number">36</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

 

<div class="p-2 pe-4">
     
        <a href="/2022/05/16/QuickJS-JavaScript%E4%B8%96%E7%95%8C%E7%9A%84%E5%8E%9F%E5%A7%8B%E5%8E%9F%E5%9E%8B%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%BB%BA%E7%AB%8B/" class="btn btn-outline-secondary btn-sm float-start">
            <small>
                < 上一篇：QuickJS JavaScript世界的原始原型对象的建立
            </small>
        </a>
     
     
        <a href="/2022/05/05/QuickJS-JSString-JSAtom/" class="btn btn-outline-secondary btn-sm float-end" >
            <small>
                下一篇：QuickJS JSString&JSAtom >
            </small>
        </a>
     
</div>
                        </div>
                    </div>

                    <!-- sidebar -->
                    <div id="slidebar">
                        <div class="border-auto ps-2 pe-1 pb-2 pt-2">
    
        <!-- 侧边栏 分类 -->
<div class="card mb-3">
    <h6 class="card-header tag-hover"><i class="fa fa-folder-open pe-2"></i>分类
        
    </h6>
    <div class="card-body">
        <ul class="list-group border-0">
            
            
             
            <a class="list-group-item border-0 pt-0 pb-0 ps-1" href="/categories/QuickJS/ ">
                QuickJS <span class="badge bg-secondary float-end m-1">3</span>
            </a>
              
        </ul>

        <ul class="list-group border-0 collapse" id="category">
            
        </ul>
    </div>
</div>

 
    
        <!-- 侧边栏 标签 -->
<div class="card mb-3">
    <h6 class="card-header tag-hover"><i class="fa fa-tag pe-2"></i>标签
        
    </h6>

    <div class="card-body tag-hover">
        
        
             
            <a class="text-decoration-none border-0 d-inline-flex link-dark pt-0 pb-0 p-0" href="/tags/QuickJS/ ">
                QuickJS <span class="badge bg-secondary float-end m-1">6</span>
            </a>
          

        <span id="tags" class="collapse">
            
        </span>
    </div>
</div>
 
    
        <div class="card mb-3">
    <h6 class="card-header"><i class="fa fa-clock-o pe-2"></i>最近文章</h6>
    <div class="card-body tag-hover">
        <ul class="list-group border-0">
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/05/QuickJS-JSString-JSAtom/ ">
                    <small> QuickJS JSString&JSAtom </small>
                </a>
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/05/QuickJS%E5%AD%97%E8%8A%82%E7%A0%81%E6%89%93%E5%8D%B0/ ">
                    <small> QuickJS字节码打印 </small>
                </a>
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/05/QuickJS%E6%93%8D%E4%BD%9C%E7%A0%81/ ">
                    <small> QuickJS操作码 </small>
                </a>
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/12/QuickJS%E6%95%B0%E5%AD%97%E5%AD%97%E9%9D%A2%E9%87%8F/ ">
                    <small> QuickJS数字字面量 </small>
                </a>
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/16/QuickJS-JavaScript%E4%B8%96%E7%95%8C%E7%9A%84%E5%8E%9F%E5%A7%8B%E5%8E%9F%E5%9E%8B%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%BB%BA%E7%AB%8B/ ">
                    <small> QuickJS JavaScript世界的原始原型对象的建立 </small>
                </a>
            
             
        </ul>
    </div>
</div> 
    
        <div class="card mb-3">
    <h6 class="card-header"><i class="fa fa-link pe-2"></i>友情链接</h6>
    <div class="card-body tag-hover">
        <ul class="list-group border-0">
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6 text" target="_blank" rel="noopener" href="https://blog.csdn.net/jayyuz ">
                    <small>CSDN</small>
                </a>
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6 text" target="_blank" rel="noopener" href="https://smartlink.xin ">
                    <small>Smartlink</small>
                </a>
             
        </ul>
    </div>
</div> 
    
</div>
                    </div>
                </div>
            </main>


            <!-- footer -->
            <footer id="footer" class="bg-dark pt-3 pb-0 mt-5">
    <div class="container pb-4 pt-4 text-center">
        <p class="text-muted tag-hover"> Copyright © 2022 <a class="link-secondary text-decoration-none" target="_blank" rel="noopener" href="https://hexo.io"> SmartLink </a><br> <a class="link-secondary text-decoration-none" target="_blank" rel="noopener" href="https://github.com/smile-yan/hexo-theme-heyan"> Hexo </a> Theme <a class="link-secondary text-decoration-none" target="_blank" rel="noopener" href="https://github.com/smile-yan/hexo-theme-heyan"> heyan </a> 
            <br>
            <a class="link-secondary text-decoration-none" target="_blank" rel="noopener" href="https://beian.miit.gov.cn/#/Integrated/index">
                 
            </a>
        </p>
    </div>
</footer>
    <!-- hexo injector body_end start -->
<script src="/assets/prism-bundle.js"></script>
<script src="/assets/prism-plus.js" data-pjax=""></script>
<!-- hexo injector body_end end --><!-- hexo-inject:begin --><!-- hexo-inject:end --></body>
    <script>
        // 获取屏幕高度 document.documentElement.clientHeight
        console.log(document.documentElement.clientHeight);
        // 获取屏幕宽度 document.documentElement.clientWidth
        console.log(document.documentElement.clientWidth);
        if (document.documentElement.clientHeight > document.documentElement.clientWidth) {
            console.log('remove slidebar')
            document.getElementById("slidebar").remove()
            document.getElementById("content").className = "col-md-12";//单个class  
        } else {
            document.getElementById("slidebar").className = "col-md-2";//单个class  
            document.getElementById("content").className = "col-md-10";//单个class  
        }
    </script>
    <!-- https://cdn.jsdelivr.net/npm/vanta@0.5.22/dist/vanta.birds.min.js -->
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r121/three.min.js"></script> -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/vanta@0.5.22/dist/vanta.dots.min.js"></script>
    <script>
        VANTA.DOTS({
            el: "#footer",
            mouseControls: true,
            touchControls: true,
            gyroControls: false,
            minHeight: 200.00,
            minWidth: 200.00,
            scale: 1.00,
            scaleMobile: 1.00,
            size: 2.20,
            spacing: 13.00
        })
    </script> -->

    <!-- <script src="https://cdn.jsdelivr.net/npm/vanta@0.5.22/dist/vanta.clouds2.min.js"></script>
    <script>
        VANTA.CLOUDS2({
            el: "#footer",
            mouseControls: true,
            touchControls: true,
            gyroControls: false,
            minHeight: 200.00,
            minWidth: 200.00,
            scale: 1.00,
            speed: 2.10,
            texturePath: "https://www.vantajs.com/gallery/noise.png"
        })
    </script> -->

</html>